package com.example.teemor.es_demo.config;

import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import jakarta.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@EnableJpaRepositories(
    basePackages = "com.example.teemor.es_demo.repository.jpa",
    entityManagerFactoryRef = "primaryEntityManagerFactory",
    transactionManagerRef = "primaryTransactionManager"
)
@EnableElasticsearchRepositories(basePackages = "com.example.teemor.es_demo.repository.es")
@EntityScan("com.example.teemor.es_demo.entity")
@EnableTransactionManagement
public class DataSourceConfig {

    // /**
    //  * PostgreSQL 主数据源
    //  */
    // @Primary
    // @Bean(name = "primaryDataSource")
    // @ConfigurationProperties(prefix = "spring.datasource")
    // public DataSource primaryDataSource() {
    //     return DataSourceBuilder.create().type(HikariDataSource.class).build();
    // }

  // 保留这个 Bean，它负责从配置文件读取属性
    @Primary
    @Bean
    @ConfigurationProperties("spring.datasource") // 这个 Bean 读取 spring.datasource 前缀的配置
    public DataSourceProperties primaryDataSourceProperties() {
        return new DataSourceProperties();
    }

    /**
     * PostgreSQL 主数据源
     * 使用 DataSourceProperties 来正确初始化 HikariDataSource
     */
    @Primary
    @Bean(name = "primaryDataSource")
    public DataSource primaryDataSource() {
        // 通过 primaryDataSourceProperties Bean 获取已绑定配置的 DataSourceProperties 实例
        DataSourceProperties properties = primaryDataSourceProperties();
        
        // 使用 DataSourceProperties 的 initializeDataSourceBuilder 方法
        // 并指定类型为 HikariDataSource，然后构建
        // 这种方式能更可靠地处理属性映射和初始化
        return properties.initializeDataSourceBuilder()
                          .type(HikariDataSource.class)
                          .build();
    }


    // /**
    //  * MySQL 数据源
    //  */
    // @Bean(name = "mysqlDataSource")
    // @ConfigurationProperties(prefix = "spring.custom.datasource.mysql")
    // public DataSource mysqlDataSource() {
    //     return DataSourceBuilder.create().type(HikariDataSource.class).build();
    // }

    /**
     * ClickHouse 数据源
     */
    @Bean(name = "clickhouseDataSource")
    @ConfigurationProperties(prefix = "spring.custom.datasource.clickhouse")
    public DataSource clickhouseDataSource() {
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }

    /**
     * PostgreSQL EntityManagerFactory
     */
    @Primary
    @Bean(name = "primaryEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(
            @Qualifier("primaryDataSource") DataSource dataSource) {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource);
        em.setPackagesToScan("com.example.teemor.es_demo.entity");
        
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        
        Properties properties = new Properties();
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
        properties.setProperty("hibernate.hbm2ddl.auto", "update");
        properties.setProperty("hibernate.show_sql", "true");
        properties.setProperty("hibernate.format_sql", "true");
        em.setJpaProperties(properties);
        
        return em;
    }

    /**
     * PostgreSQL TransactionManager
     */
    @Primary
    @Bean(name = "primaryTransactionManager")
    public PlatformTransactionManager primaryTransactionManager(
            @Qualifier("primaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }

    // /**
    //  * MySQL JdbcTemplate
    //  */
    // @Bean(name = "mysqlJdbcTemplate")
    // public JdbcTemplate mysqlJdbcTemplate(@Qualifier("mysqlDataSource") DataSource dataSource) {
    //     return new JdbcTemplate(dataSource);
    // }

    /**
     * ClickHouse JdbcTemplate
     */
    @Bean(name = "clickhouseJdbcTemplate")
    public JdbcTemplate clickhouseJdbcTemplate(@Qualifier("clickhouseDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}